#include "cansetmodel.h"
#include <qdebug.h>
#include "cre_mes.h"

typedef struct _BaudRateInfo
{
    QString name;
    char* value;
}BaudRateInfo;

static const BaudRateInfo kBaudRateInfo[] =
{
    {"500Kbps","500000"},
    {"250Kbps","250000"}
};

CanSetModel::CanSetModel(QObject *parent) : QObject(parent)
{

}

void CanSetModel::SetPara(int type, int dev_index, int CHN_index,int baud)
{
    this->DeviceType = type;
    this->DeveiceIndex = dev_index;
    this->Channel_index = CHN_index;
    if(baud==500*1000)
    {baud_index=0;}else {
        baud_index=1;
    }
}

void CanSetModel::DataReceive()
{
    ZCAN_Receive_Data can_data[100];
    ZCAN_ReceiveFD_Data canfd_data[100];
    UINT len;
    qDebug()<<"DataReceive Thread Start" ;
    while(isStart)
    {
        if (len = ZCAN_GetReceiveNum(chHandle, TYPE_CAN))
        {// qDebug()<<len;
            len = ZCAN_Receive(chHandle, can_data, 100, 50);
            AddData(can_data, len);
        }else {
            QThread::msleep(1);
        }

    }
    qDebug()<<"DataReceive Thread quit" ;
}

void CanSetModel::AddData(const ZCAN_Receive_Data *data, UINT len)
{
    QString item;
    for (UINT i = 0; i < len; ++i)
    {
        const ZCAN_Receive_Data& can = data[i];
        const canid_t& id = can.frame.can_id;

        CanDataBase *cdb = new CanDataBase();
        cdb->SetTime(data[i].timestamp);

        cdb->ZCAN_data=data[i];
        QByteArray arry_data;
        for (int var = 0; var < can.frame.can_dlc; ++var) {
            arry_data.append(can.frame.data[var]);
        }
        cdb->SetData(GET_ID(id),arry_data,can.frame.can_dlc,IS_EFF(id),IS_RTR(id));
        AddData(cdb);
    }
}

void CanSetModel::AddData(CanDataBase *cdb)
{
    cdb->SetTime(QDateTime::currentDateTime());
    if(cdb->IsCCP_protocol)
    {
        if(CRE_Mes::REV_Data_response(cdb,this->currentSendMsg))
        {
            if((this->currentSendMsg!=nullptr) && (this->currentSendMsg->sem!=nullptr))
            {
                this->currentSendMsg->sem->release();
            }
            delete this->currentSendMsg;
            this->currentSendMsg=nullptr;
        }
    }

    if(cdb->Id==Rev_UDS_CANID)
    {
        emit UDS_RevData_Sig(cdb);
    }

    //    QStringList strlist;
    //    strlist.append(QDateTime::currentDateTime().toString("HH:mm:ss:zzz") +QString::number(cdb->Id,16).toUpper()+"  "+cdb->StrData);
    //    emit Debug_MSG(strlist);
    emit this->DataUpdata(cdb);
}

bool CanSetModel::CanConnect()
{

    QStringList strlist;
    //ZCAN_USBCAN_2E_U为设备类型,  请根据实际修改
    dhandle = ZCAN_OpenDevice(DeviceType, DeveiceIndex, 0);
    if (INVALID_DEVICE_HANDLE == dhandle)
    {
        qDebug()<< __func__<<__LINE__<<"打开设备失败";
        strlist.append("CAN卡未打开");
        emit Debug_MSG(strlist);
        return false;
    }
    property = GetIProperty(dhandle);
    if (NULL == property)
    {
        qDebug()<< __func__<<__LINE__<<"属性指针为空";
        ReleaseIProperty(property);
        ZCAN_CloseDevice(dhandle);
        strlist.append("CAN卡未打开：属性指针为空");
        emit Debug_MSG(strlist);
        return false;
    }
    ZCAN_CHANNEL_INIT_CONFIG cfg;

    if (property->SetValue("0/baud_rate", kBaudRateInfo[baud_index].value) != STATUS_OK)
    {
        qDebug() <<  __func__<<__LINE__<<"设置波特率失败" ;
        ReleaseIProperty(property);
        ZCAN_CloseDevice(dhandle);
        strlist.append("CAN卡未打开：设置波特率失败");
        emit Debug_MSG(strlist);
        return false;
    }

    memset(&cfg, 0, sizeof(cfg));
    cfg.can_type = TYPE_CAN;//CANFD设备为TYPE_CANFD
    cfg.can.filter = 0;
    cfg.can.mode = 0; //正常模式, 1为只听模式
    cfg.can.acc_code = 0;
    cfg.can.acc_mask = 0xffffffff;

    int CHN_number=0;//通道号
    chHandle = ZCAN_InitCAN(dhandle, CHN_number, &cfg);
    if (INVALID_CHANNEL_HANDLE == chHandle)
    {
        qDebug()<< __func__<<__LINE__<<"初始化通道失败";
        ReleaseIProperty(property);
        ZCAN_CloseDevice(dhandle);
        strlist.append("CAN卡未打开：初始化通道失败");
        emit Debug_MSG(strlist);
        return false;
    }
    if (ZCAN_StartCAN(chHandle) != STATUS_OK)
    {

        qDebug()<< __func__<<__LINE__<<"启动通道失败";
        ReleaseIProperty(property);
        ZCAN_CloseDevice(dhandle);
        strlist.append("CAN卡未打开：启动通道失败");
        emit Debug_MSG(strlist);
        return false;
    }
    isStart =true;
    qDebug()<< __func__<<__LINE__<<"CAN启动成功";

    strlist.append("CAN启动成功");
    emit Debug_MSG(strlist);
    ZCAN_ClearBuffer(chHandle);
    return true;
}

void CanSetModel::CanClose()
{
    ReleaseIProperty(property);
    if(isStart)
    {
        isStart = false;
        ZCAN_CloseDevice(dhandle);
    }
    qDebug()<<  "CanSetModel CanClose: ";
    QStringList strlist;
    strlist.append("CAN卡已关闭");
    emit Debug_MSG(strlist);
    //QLOG_INFO()<<  "CanSetModel QThreadid: "<<  QThread::currentThreadId();
    //    QThread::currentThread()->quit();
}

uint CanSetModel::CanSend(ZCAN_Transmit_Data* pTransmit, UINT len)
{
    uint sednum=ZCAN_Transmit(chHandle, pTransmit, len);
    if(sednum<len)
    {
        QStringList strlist;
        qDebug()<< __func__<<__LINE__ << "发送数据部分失败" <<"总长度:"<<len<<"实际发送数量："<<sednum;
        strlist.append("发送数据部分失败");
        emit Debug_MSG(strlist);
    }
    return sednum;
}

bool CanSetModel::CanSend(CanDataBase *data)
{
    current_CTR=(current_CTR+1)&0xFF;
    data->_data[1]=this->current_CTR&0xFF;
    data->GetStringData();
    bool sedsta=false;
    ZCAN_Transmit_Data frame;
    memset(&frame, 0, sizeof(frame));

    frame.frame.can_id = data->Id ;
    if(data->IsExtendFrame)
    {        frame.frame.can_id=frame.frame.can_id|0x80000000;    }
    frame.frame.can_dlc =data->Len;
    for( int i = 0; i < data->Len; i++ )
    {
        frame.frame.data[i] =  data->_data.at(i);
    }
    frame.transmit_type=data->transmit_type%4;

    if (ZCAN_Transmit(chHandle, &frame, 1) != 1)
    {
        QStringList strlist;

        if (ZCAN_Transmit(chHandle, &frame, 1) != 1)
        {


            qDebug()<< __func__<<__LINE__ << "发送数据失败" ;
            strlist.append("发送数据失败");
            emit Debug_MSG(strlist);
            return sedsta;
        }else {

            this->currentSendMsg=data;
            sedsta=true;
            strlist<<"补发数据 ID："<<QString::number(data->Id,16) <<"  Data: "<<data->StrData;
            qDebug()<<strlist;
            emit Debug_MSG(strlist);
            return sedsta;
        }

    }else {
        //  qDebug()<< __func__<<__LINE__ << "发送数据ok" <<frame.frame.can_id;
    }
    //   emit send_Sta(sedsta);
    // data->sTime = frame.

    this->currentSendMsg=data;
    sedsta=true;
    return sedsta;
}

